import hashlib
import logging
from datetime import datetime
from typing import Any, List

from fastapi import APIRouter, Depends, Body, HTTPException, Path, UploadFile, File, Form
from fastapi.params import Param
from sqlalchemy import or_
from sqlalchemy.orm import Session, Query

from app.core.security import get_current_user
from app.db.session import get_db
from app.llama_index.session.livsm_session import livsmSessions, MilvusVectorStoreSession
from app.models import User, KnowledgeBase, Document
from app.models.knowledge import  KnowledgeBaseStatus, DocumentStatus
from app.models.log import OpenaiLog, FuncallLog
from app.schemas.base_so import BaseListQo, DelParam, DocumentListQo, ChangeStatusParam, ChangeStatusToDraftParam, \
    DetailParam
from app.schemas.knowledge_base import KnowledgeBaseCreate, KnowledgeBaseUpdate, DocumentUpdate
from app.schemas.log import OpenaiLogListQo, FuncallLogListQo
from app.schemas.result import BaseResult, okResult, errResult, BaseListResult
from app.services.factory.embedding_factory import EmbeddingsFactory
from app.services.file_services import asave_kb_file, FilePathInfo, delete_kb_file, format_file_name_to_read
from app.services.knowledge_services import knowledge_services_change_knowledge_doc_status
from app.utils.str_utils import format_filename

logger = logging.getLogger(__name__)
router = APIRouter()


@router.post("/openai/list", response_model=BaseListResult)
async def get_openai_log_list(
        db: Session = Depends(get_db),
        current_user: User = Depends(get_current_user),
        qo:OpenaiLogListQo=Body()
) -> Any:
    page=qo.pageNum
    per_page = qo.pageSize
    offset = (page - 1) * per_page
    conditions=[]
    if qo.searchValue:
        conditions.append(
            or_(OpenaiLog.request_body.like(f"%{qo.searchValue}%"), OpenaiLog.response_body.like(f"%{qo.searchValue}%")))
    if qo.chat_id:
        conditions.append(OpenaiLog.chat_id == qo.chat_id)


    query:Query=(db.query(OpenaiLog)
        .filter(*conditions)
         )

    total=query.count()

    rows = (
        query
        .order_by(OpenaiLog.id.desc())
        .limit(per_page)
        .offset(offset)
        .all()
    )
    return BaseListResult(
        rows=rows,
        total=total,
    ).json_encoders()


@router.delete("/openai/delete")
async def delete_ai_tools(
        *,
        db: Session = Depends(get_db),
        param: DelParam = Body(),
        current_user: User = Depends(get_current_user)
) -> Any:
    """
    Delete Tools.
    """
    ids = param.ids

    query = (
        db.query(OpenaiLog)
        .filter(
            OpenaiLog.id.in_(ids),
        )
    )
    query.delete()
    db.commit()
    return okResult()


@router.post("/funcall/list", response_model=BaseListResult)
async def get_funcall_log_list(
        db: Session = Depends(get_db),
        current_user: User = Depends(get_current_user),
        qo:FuncallLogListQo=Body()
) -> Any:
    page=qo.pageNum
    per_page = qo.pageSize
    offset = (page - 1) * per_page
    conditions=[]
    if qo.searchValue:
        conditions.append(
            or_(FuncallLog.description.like(f"%{qo.searchValue}%")))


    query:Query=(db.query(FuncallLog)
                 .filter(*conditions)
                 )

    total=query.count()

    rows = (
        query
        .order_by(FuncallLog.id.desc())
        .limit(per_page)
        .offset(offset)
        .all()
    )
    return BaseListResult(
        rows=rows,
        total=total,
    ).json_encoders()


@router.post("/funcall/getDetail", response_model=BaseResult)
def get_funcall_log(
        *,
        db: Session = Depends(get_db),
        param: DetailParam = Body(),
        current_user: User = Depends(get_current_user)
) -> Any:
    """
    Get funcall_log by ID.
    """

    item = (
        db.query(FuncallLog)
        .filter(
            FuncallLog.id == param.id,
            )
        .first()
    )

    if not item:
        raise HTTPException(status_code=500, detail="找不到日志")


    return okResult(data=item).json_encoders()
@router.delete("/funcall/delete")
async def delete_ai_tools(
        *,
        db: Session = Depends(get_db),
        param: DelParam = Body(),
        current_user: User = Depends(get_current_user)
) -> Any:
    """
    Delete Tools.
    """
    ids = param.ids

    query = (
        db.query(FuncallLog)
        .filter(
            FuncallLog.id.in_(ids),
        )
    )
    query.delete()
    db.commit()
    return okResult()
